/*
 * Created on Jul 11, 2004
 */
package dk.aiszone.lang.autosource.formatter;

import java.util.Iterator;
import java.util.List;
import java.util.StringTokenizer;

import dk.aiszone.lang.autosource.generatorobjects.interfaces.BodyContainer;
import dk.aiszone.lang.autosource.generatorobjects.interfaces.SimpleBlockObject;

/**
 * Helper class for the autosource generators
 * 
 * @author <a href="mailto:ais@mail.dk">Ais</a>
 * @since 1.0
 * @version 1.0
 */
/* pp */class Helper {

    /**
     * Formats the supplied <code>List</code> of <code>BlockObjects</code>.<br>
     * The supplied <code>List</code> is broken down into lines (&#47;n)<br>
     * and each line is indentet with the number of tabs specified by the <code>level</code> argument.<br>
     * Each line ending with a <b>{</b> character causes the number of indentions increates by one.<br>
     * Each line ending beginning with a <b>}</b> character causes the number of indentions decrease by one.<
     * 
     * @param body
     *            The <code>List</code> of <code>BlockObjects</code> to format
     * @param level
     *            The number of indentions
     * @return The formatted <code>String</code>
     */
    /* pp */static StringBuilder formatBody(List<SimpleBlockObject> body, int level) {
        StringBuilder java = new StringBuilder();
        handleBlockObjects(java, level, body);
        return java;
    }

    /**
     * Wraps the supplied <code>comment</code> with <b>&#47;&#42;*</b> and <b>&#42;&#47;</b> signs.
     * 
     * @param comment
     *            The comment to wrap.
     * @return Wrapped comment.
     */
    /* pp */static String formatComment(String comment) {
        return "/*\n * " + comment + "\n */\n";
    }

    /**
     * Creates a <code>String</code> of &quot;tabs&quot; (represented as 4 spaces).
     * 
     * @param level
     *            The number of tabs.
     * @return <code>String</code> of tabs.
     */
    /* pp */static String getTabs(int level) {
        StringBuffer tmp = new StringBuffer(level * 4);
        for (int i = 0; i < level; i++) {
            tmp.append("    ");
        }
        return tmp.toString();
    }

    private static int handleBlockObjects(StringBuilder java, int level, List<SimpleBlockObject> body) {
        for (Iterator<SimpleBlockObject> iterator = body.iterator(); iterator.hasNext();) {
            SimpleBlockObject blockObject = iterator.next();

            if (blockObject instanceof BodyContainer) {
                level = handleBlockObjects(java, level, ((BodyContainer)blockObject).getBodyParts());
            } else {
                level = handleBodyPart(java, level, blockObject);
            }
        }
        return level;
    }

    private static int handleBodyPart(StringBuilder result, int level, SimpleBlockObject java) {
        StringTokenizer st = new StringTokenizer(java.toJava(), "\n");
        while (st.hasMoreTokens()) {
            String line = st.nextToken().trim();

            if (line.startsWith("}")) {
                level--;
            }

            if ("".equals(line)) {
                result.append("\n");
            } else {
                result.append(Helper.getTabs(level));
                result.append(line);
                result.append("\n");
            }

            if (line.endsWith("{")) {
                level++;
            }

            // TODO: Handle case in switch statements....
        }
        return level;
    }
}